package com.xyy.saas.payment.api.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.config.BusinessTypeConfig;
import com.xyy.saas.payment.cores.api.PaymentCommonApi;
import com.xyy.saas.payment.cores.bo.ChannelSwitchBO;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.cores.vo.ChannelSwitchVO;
import com.xyy.saas.payment.cores.vo.ResultVO;
import com.xyy.saas.payment.dao.model.ChannelSwitchInfo;
import com.xyy.saas.payment.dao.model.GraySwitchInfo;
import com.xyy.saas.payment.service.ChannelSwitchInfoService;
import com.xyy.saas.payment.util.ApolloUtil;
import com.xyy.saas.payment.util.DateUtil;
import com.xyy.saas.payment.util.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service(version = "1.0.0")
public class PaymentCommonApiImpl implements PaymentCommonApi {
    private static final Logger LOGGER = LoggerFactory.getLogger(PaymentCommonApiImpl.class);
    @Autowired
    private ChannelSwitchInfoService channelSwitchInfoService;

    @Autowired
    private BusinessTypeConfig businessTypeConfig;

    @Override
    public ResultVO<List<ChannelSwitchBO> > channelSwitch(ChannelSwitchVO channelSwitchVO, String sign) {
        try {
            // 参数校验
            checkChannelSwitchParam(channelSwitchVO, sign);
        }catch (PaymentException e){
            LOGGER.error("PaymentCommonApiImpl checkChannelSwitchParam error channelSwitchVO:{}, e:{}", JSON.toJSON(channelSwitchVO), e);
            ResultVO resultVO = new ResultVO();
            resultVO.setCode(e.getErrCode());
            resultVO.setMsg(e.getErrMsg());
            return resultVO;
        }catch (Exception e){
            LOGGER.error("PaymentCommonApiImpl checkChannelSwitchParam error channelSwitchVO:{}, e:{}", JSON.toJSON(channelSwitchVO), e);
            return ResultVO.createError(e.getMessage());
        }

        // 参数转换
        List<ChannelSwitchInfo> list = new ArrayList<>();
        List<String> businessIds = channelSwitchVO.getBusinessIds();
        Date now = DateUtil.now();
        for (String businessId : businessIds) {
            ChannelSwitchInfo info = new ChannelSwitchInfo();
            info.setBusinessId(businessId);
            info.setBusinessIdType(channelSwitchVO.getBusinessIdType().getType());
            info.setBusinessOrderType(channelSwitchVO.getBusinessOrderType().getType());
            info.setBusinessType(channelSwitchVO.getBusinessType().getType());
            info.setToChannel(channelSwitchVO.getToChannel().getCode());
            info.setCreateTime(now);
            info.setUpdateTime(now);
            info.setYn(1);
            list.add(info);
        }

        // 存
        List<ChannelSwitchInfo> channelSwitchInfos = channelSwitchInfoService.batchInsert(list);

        List<ChannelSwitchBO> result = new ArrayList<>();
        for (ChannelSwitchInfo channelSwitchInfo : channelSwitchInfos) {
            ChannelSwitchBO channelSwitchBO = new ChannelSwitchBO();
            BeanUtils.copyProperties(channelSwitchInfo, channelSwitchBO);
            result.add(channelSwitchBO);
        }
        return ResultVO.createSuccess(result);
    }

    private void checkChannelSwitchParam(ChannelSwitchVO channelSwitchVO, String sign) throws PaymentException, IllegalAccessException {
        if(null == channelSwitchVO) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
        if(null == channelSwitchVO.getInvoker()) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
        if(null == channelSwitchVO.getBusinessIds() || channelSwitchVO.getBusinessIds().isEmpty()){
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
        if(null == channelSwitchVO.getToChannel()){
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }

        if(!businessTypeConfig.checkAllType(channelSwitchVO.getBusinessType().getType(), channelSwitchVO.getBusinessIdType().getType(), channelSwitchVO.getBusinessOrderType().getType())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }

        String publicKey = ApolloUtil.getProperty(channelSwitchVO.getInvoker().getType()+ Constants.PUBLIC);
        //验签
        if(!SignUtil.doCheck(channelSwitchVO, sign, publicKey)){
            throw new PaymentException(ResultCodeEnum.SIGN_ERROR);
        }

    }

}
